#include "stdafx.h"
#include "HeightMap.h"
#include "Constant.h"

HeightMap::HeightMap() : HeightData(NULL),
m_iCols(0),
m_iRows(0)
{
}

void HeightMap::Init(char *fileRAW, int iRows, int iCols, float fHeightScale, float fHeightOffset)
{
	m_iRows = iRows;
	m_iCols = iCols;
	heightSrc = LoadRAW(fileRAW);
	if(heightSrc == NULL)
	{
		return;
	}
	int idx = 0;
	HeightData = new GLfloat[iRows * iCols];
	//Render heightmap

	//GLubyte temp;
	//GLubyte red, green, blue, height;
	//for(int i=0; i<iRows; i++)
	//{
	//	for(int j=0; j<iCols; j++)
	//	{			
	//		temp = heightSrc[idx];
	//		red = temp & 11100000;
	//		green = temp & 00011100;
	//		blue = temp & 0000011;

	//		height = (red + green + blue) / 3;
	//		idx = i*iRows+j;
	//		HeightData[idx] = (GLfloat)((float)(height)*fHeightScale);
	//	}
	//}
	GLushort temp;
	GLushort red, green, blue;
	GLushort height;
	for(int i=0; i<iRows; i++)
	{
		for(int j=0; j<iCols; j++)
		{
			temp = heightSrc[idx];
			red = temp & 1111100000000000;
			green = temp & 0000011111100000;
			blue = temp & 0000000000011111;
			height = (red + green + blue) / 3;
			height=height/256;
			idx = i*iRows+j;
			HeightData[idx] = (GLfloat)((float)(height)*fHeightScale);
		}
	}
	Filter3x3();
}

GLushort * HeightMap::LoadRAW(char *fileRAW)
{
	GLushort * pOutputBuffer;
	FILE *pFile = NULL;
	pFile = fopen(fileRAW, "rb");
	if(pFile == NULL)
	{
		return NULL;
	}
	fseek(pFile, 0, SEEK_END);
	int iFileSize = ftell(pFile);
	fseek(pFile, 0, SEEK_SET);

	pOutputBuffer = new GLushort[iFileSize];
	fread(pOutputBuffer, 2, iFileSize/2, pFile);
	pOutputBuffer[iFileSize] = '\0';
	fclose(pFile);

	return pOutputBuffer;
}

bool HeightMap::InBounds(int i, int j)
{
	if(i>= 0 && i< m_iRows &&
		j >= 0 && j< m_iCols)
		return true;
	return false;
}

GLfloat HeightMap::Sampler3x3(int i, int j)
{
	float avg = 0.0f;
	float num = 0.0f;
	for(int r = i-1; r <= i+1; ++r)
	{
		for(int c = j-1; c <= j+1; ++c)
		{
			if(InBounds(r,c))
			{
				avg += HeightData[r*m_iRows+c];
				num += 1.0f;
			}
		}
	}
	return (GLfloat)(avg / num);
}

void HeightMap::Filter3x3()
{
	GLfloat *temp = new GLfloat[m_iRows * m_iCols];
	for(int i=0; i<m_iRows; i++)
	{
		for(int j=0; j<m_iCols; j++)
		{
			temp[i*m_iCols + j] = Sampler3x3(i, j);
		}
	}

	SAFE_DEL_ARRAY(HeightData);
	HeightData = temp;
}

HeightMap::~HeightMap()
{
	SAFE_DEL_ARRAY(HeightData);
	//SSAFE_DEL_ARRAY(heightSrc);
}